package com.cqvip.innocence.project.controller.admin;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cqvip.innocence.common.annotation.Log;
import com.cqvip.innocence.project.controller.AbstractController;
import com.cqvip.innocence.project.model.dto.JsonResult;
import com.cqvip.innocence.project.model.entity.AdminRole;
import com.cqvip.innocence.project.model.entity.Resource;
import com.cqvip.innocence.project.model.entity.Role;
import com.cqvip.innocence.project.model.entity.RoleResource;
import com.cqvip.innocence.project.model.enums.BusinessType;
import com.cqvip.innocence.project.service.AdminRoleService;
import com.cqvip.innocence.project.service.ResourceService;
import com.cqvip.innocence.project.service.RoleResourceService;
import com.cqvip.innocence.project.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Innocence
 * @since 2020-07-13
 */
@RestController
@RequestMapping("/${base-url.system}/role/")
@Api(tags = "角色操作接口")
public class RoleController extends AbstractController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleResourceService roleResourceService;

    @Autowired
    private AdminRoleService adminRoleService;

    @Autowired
    private ResourceService resourceService;

    @GetMapping("getRolesPage")
    @ApiOperation("获取角色列表分页")
    @ApiImplicitParam(name = "name", value = "角色名,不支持模糊检索", dataTypeClass = String.class)
    public JsonResult getRoles(String name) {
        Page page = getPageParams();
        Page<Role> roles = roleService.getRolesPage(name, page);
        roles.getRecords().forEach(role -> {
            if (role.getResourceStr() == null) {
                return;
            }
            String[] split = role.getResourceStr().split(",");
            List<Long> ids = new ArrayList<>();
            for (String id : split) {
                ids.add(Long.parseLong(id));
            }
            role.setResourceIds(ids);
        });
        return JsonResult.Get("roles", roles);
    }

    @GetMapping("getAllRoles")
    @ApiOperation("获取所有角色列表")
    public JsonResult getAllRoles() {
        return JsonResult.Get().putList(roleService.list());
    }

    @PostMapping("addOrEdit")
    @ApiOperation("新增或编辑角色")
    @Log(title = "新增或编辑角色", businessType = BusinessType.SAVE_OR_UPDATE)
    @Transactional(rollbackFor = Exception.class)
    @PreAuthorize("hasAnyAuthority('admin:role:*')")
    public JsonResult addOrEditRole(@RequestBody Role role) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getName, role.getName())
                .ne(role.getId() != null, Role::getId, role.getId());
        List<Role> roles = roleService.list(wrapper);
        if (roles.size() > 0) {
            return JsonResult.Get(false, "不能存在相同角色名!");
        }
        roleService.saveOrUpdate(role);
        List<Long> list = role.getResourceIds();
        if (!CollectionUtils.isEmpty(list)) {
            roleResourceService.removeById(role.getId());
            List<RoleResource> roleResources = new ArrayList<>();
            for (Long id : list) {
                RoleResource roleResource = new RoleResource();
                roleResource.setRoleId(role.getId());
                roleResource.setResourceId(id);
                roleResources.add(roleResource);
            }
            roleResourceService.saveBatch(roleResources);
        }
        return JsonResult.Get(true);
    }

    @PostMapping("delete")
    @ApiOperation("根据id删除角色信息;参数名：ids，含义：需要删除的角色id集合")
    @Log(title = "删除角色", businessType = BusinessType.DELETE)
    @PreAuthorize("hasAnyAuthority('admin:role:*')")
    public JsonResult deleteRole(@RequestBody List<Long> ids) {
        if (ids.size() <= 0) {
            return JsonResult.Get(false, "请传入需要删除的数据！");
        }
        LambdaQueryWrapper<RoleResource> roleResourceWrapper = new QueryWrapper<RoleResource>().lambda();
        LambdaQueryWrapper<AdminRole> adminRoleWrapper = new QueryWrapper<AdminRole>().lambda();
        for (int i = 0; i < ids.size(); i++) {
            roleResourceWrapper.eq(RoleResource::getRoleId, ids.get(i));
            adminRoleWrapper.eq(AdminRole::getRoleId, ids.get(i));
            roleResourceService.remove(roleResourceWrapper);
            adminRoleService.remove(adminRoleWrapper);
        }
        roleService.removeByIds(ids);
        return JsonResult.Get();
    }

    @GetMapping("getResourceByRole")
    @ApiOperation("根据当前角色获取资源权限信息")
    @ApiImplicitParam(name = "roleId", value = "角色id", dataTypeClass = Long.class, required = true)
    public JsonResult getResourceByRole(Long roleId) {
        if (roleId == null) {
            return JsonResult.Get(false);
        }
        LambdaQueryWrapper<RoleResource> wrapper = new QueryWrapper<RoleResource>().lambda();
        wrapper.eq(RoleResource::getRoleId, roleId);
        List<RoleResource> list = roleResourceService.list(wrapper);
        List<Long> ids = new ArrayList<>();
        for (RoleResource r : list) {
            ids.add(r.getResourceId());
        }
        List<Long> collect = ids.stream().distinct().collect(Collectors.toList());
        List<Resource> resources = resourceService.listByIds(collect);
        return JsonResult.Get().putList(resources);
    }
}

